import {
  DeviceOrientationCamera,
  Mesh,
  MeshBuilder,
  Scene,
  UniversalCamera,
  Vector3,
  VideoTexture,
} from "@babylonjs/core";
import { CustomMaterial } from "@babylonjs/materials";
export default class TransparentVideo {
  private videoGeometry: Mesh;
  // 宽容度
  public tolerance: number = 0.5
  // 颜色
  public chromaKey: Vector3 = new Vector3(0,0,1);
  private TransparentVideoShader = `
    float dis = distance(color.rgb, chromaKey);
    if(
      (color.r < color.b) && (color.g < color.b)
    ){
      if(
        dis < tolerance
      ){
          discard;
      }else if(
        (dis >= tolerance)&&(dis <= tolerance+0.2)
      ){
          color.a = 0.1;
      }
    }
    `;
  /**
   * @Descripttion:
   * @Author: 刘译蓬
   * @msg:
   * @param {string} name
   * @param {object} size
   * @param {string} video
   * @param {Scene} scene
   * @return {*}
   */
  constructor(
    name: string,
    size: { width: number; height: number },
    video: string | string[] | HTMLVideoElement,
    camera: UniversalCamera | DeviceOrientationCamera,
    scene: Scene,
    isPanorama: boolean
  ) {
    // initplane
    this.videoGeometry = this.initplane(name, size, video, scene, isPanorama);
    scene.registerBeforeRender(() => {
      if (isPanorama) {
        this.videoGeometry.position = camera.position;
      } else {
        this.videoGeometry.position.x = camera.getFrontPosition(2).x;
        this.videoGeometry.position.z = camera.getFrontPosition(2).z;
        this.videoGeometry.position.y = 0.9;
      }
    });
  }

  /**
   * @Descripttion:
   * @Author: 刘译蓬
   * @msg:
   * @param {string} name
   * @param {object} size
   * @return {*}
   */
  private initplane(
    name: string,
    size: { width: number; height: number },
    video: string | string[] | HTMLVideoElement,
    scene: Scene,
    isPanorama: boolean
  ) {
    let videoGeometry: Mesh;
    if (isPanorama) {
      videoGeometry = MeshBuilder.CreateSphere(name, { sideOrientation: 3 });
      videoGeometry.scaling.y = -1;
    } else {
      videoGeometry = MeshBuilder.CreatePlane(name, size);
      videoGeometry.billboardMode = 2;
    }
    const videoMat = new CustomMaterial("video material", scene);
    videoMat.needAlphaBlending = () => true;
    videoMat.AddUniform('tolerance','float',undefined) // 添加Uniform传参
    videoMat.AddUniform('chromaKey','vec3',undefined) // 添加Uniform传参
    videoMat.backFaceCulling = false;
    videoMat.Fragment_Before_FragColor(this.TransparentVideoShader); // 设置片元着色器
    videoMat.onBindObservable.add(() => {
      // 把tolerance和this.tolerance_vec3给他妈绑上
      videoMat.getEffect().setFloat("tolerance", this.tolerance);
      videoMat.getEffect().setVector3("chromaKey", this.chromaKey);
    });
    const myVideoTexture = new VideoTexture("video", video, scene);
    myVideoTexture.irradianceTexture;
    videoMat.emissiveTexture = myVideoTexture;
    videoMat.disableLighting = true;
    videoGeometry.material = videoMat;
    return videoGeometry;
  }
}
